/**
  ******************************************************************************
  * @author     Chris
  * @since      2024/6/13 13:51
  *
  * @file       pd_timer_etr.c
  * @brief      TimerETR peripheral driver.
  *
  * @note       This file contains the peripheral driver for the TimerETR.
  *
  * @warning    None.
  ******************************************************************************
  * Change Logs:
  *   Date          Author       Notes
  *   2024/6/13     Chris        the first version
  *
  ******************************************************************************
  */

#include <stm32f4xx_ll_tim.h>
#include "pd_timer_etr.h"

static void TimerETR_init_(const TimerETR *this, IRQn_Type irQnType, uint32_t PreemptPriority, uint32_t SubPriority) {
    // GPIO init
    TimerCh_init(this->timerCh);

    // Set external trigger
    LL_TIM_ConfigETR(this->timer->TIMx, this->ETRPolarity, this->ETRPrescaler, this->ETRFilter);
    // Set clock mode
    LL_TIM_SetClockSource(this->timer->TIMx, this->ClockSource);
    // Set Timer Base Unit
    Timer_init(this->timer);

    // NVIC also can be init in main.c
    NVIC_SetPriority(irQnType, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), PreemptPriority, SubPriority));
    NVIC_EnableIRQ(irQnType);

    // Set Update Interrupt
    LL_TIM_EnableIT_UPDATE(this->timer->TIMx);
    // Enable timer counter
    LL_TIM_EnableCounter(this->timer->TIMx);
    // Enable external clock
    LL_TIM_EnableExternalClock(this->timer->TIMx);
}

void TimerETR_constructor(TimerETR *this, Timer *timer, TimerCh *timerChannel) {
    static struct TimerETRVtbl vtbl = {
        .init = &TimerETR_init_,
    };

    this->vptr = &vtbl;

    this->timer = timer;
    this->timerCh = timerChannel;

    this->ETRPolarity = LL_TIM_ETR_POLARITY_NONINVERTED;
    this->ETRPrescaler = LL_TIM_ETR_PRESCALER_DIV1;
    this->ETRFilter = LL_TIM_ETR_FILTER_FDIV1;
    this->ClockSource = LL_TIM_CLOCKSOURCE_EXT_MODE2;
}
